home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
17 Bit Software 6: Level 6
/
17 Bit - Level 6 (1998)(Epic Marketing)[!].iso
/
quartz
/
q0430.dms
/
q0430.adf
/
Patch
/
util.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-02
|
13KB
|
582 lines
#include "EXTERN.h"
#include "common.h"
#include "INTERN.h"
#include "util.h"
/* Rename a file, copying it if necessary. */
#ifdef AMIGA
#include <libraries/dos.h>
#include <libraries/dosextens.h>
/* backup & copy the file */
static void copy_file();
int
move_file(from,to)
char *from, *to;
{
register long success;
register int fromfd;
register int i;
register struct FileLock *destlock;
int curnum='0';
static char bakname[256];
/* declare us some AmigaDOS functions: */
extern long DeleteFile();
extern struct FileLock *Lock();
extern void UnLock();
extern long Rename();
if (strEQ(to, "-")) { /* cat it to stdout. */
#ifdef DEBUGGING
if (debug & 4)
say2("Moving %s to stdout.\n", from);
#endif
fromfd = open(from, 0);
if (fromfd < 0)
fatal2("patch: internal error, can't reopen %s\n", from);
while ((i=read(fromfd, buf, sizeof buf)) > 0)
if (write(1, buf, i) != 1)
fatal1("patch: write failed\n");
Close(fromfd);
return 0;
}
/* add the extension to the name */
Strcpy(bakname, to);
/* see if the "to" exists. If not, don't add the extension. */
if (destlock=Lock(bakname)) {
UnLock(destlock);
Strcat(bakname, ORIGEXT);
i = strlen(bakname); /* find the end of string */
bakname[i+1]=0; /* so that the following will work: */
/* now to see if the destination exists: */
while (destlock=Lock(bakname)) {
UnLock(destlock); /* clean up after ourselves. */
bakname[i]=curnum++;
}
/* ok, now we can do the relinking! */
success = Rename(to,bakname);
if (success==0) {
say3("patch: can't backup %s, output is in %s\n",
to, from);
return -1;
}
}
/* ok, now copy the from to the to file. */
/* try renaming it first, & if that don't work, then copy it. */
success = Rename(from,to);
if (success==0) { /* if don't work, then copy! */
copy_file(from,to);
success=DeleteFile(from);
}
return 0;
}
#endif
#ifndef AMIGA
int
move_file(from,to)
char *from, *to;
{
char bakname[512];
Reg1 char *s;
Reg2 int i;
Reg3 int fromfd;
/* to stdout? */
if (strEQ(to, "-")) {
#ifdef DEBUGGING
if (debug & 4)
say2("Moving %s to stdout.\n", from);
#endif
fromfd = open(from, 0);
if (fromfd < 0)
fatal2("patch: internal error, can't reopen %s\n", from);
while ((i=read(fromfd, buf, sizeof buf)) > 0)
if (write(1, buf, i) != 1)
fatal1("patch: write failed\n");
Close(fromfd);
return 0;
}
if (origprae) {
Strcpy (bakname, origprae);
Strcat(bakname, to);
} else {
Strcpy(bakname, to);
Strcat(bakname, origext?origext:ORIGEXT);
}
if (stat(to, &filestat) >= 0) { /* output file exists */
dev_t to_device = filestat.st_dev;
ino_t to_inode = filestat.st_ino;
char *simplename = bakname;
for (s=bakname; *s; s++) {
if (*s == '/')
simplename = s+1;
}
/* find a backup name that is not the same file */
while (stat(bakname, &filestat) >= 0 &&
to_device == filestat.st_dev && to_inode == filestat.st_ino) {
for (s=simplename; *s && !islower(*s); s++) ;
if (*s)
*s = toupper(*s);
else
Strcpy(simplename, simplename+1);
}
while (unlink(bakname) >= 0) ; /* while() is for benefit of Eunice */
#ifdef DEBUGGING
if (debug & 4)
say3("Moving %s to %s.\n", to, bakname);
#endif
if (link(to, bakname) < 0) {
say3("patch: can't backup %s, output is in %s\n",
to, from);
return -1;
}
while (unlink(to) >= 0) ;
}
#ifdef DEBUGGING
if (debug & 4)
say3("Moving %s to %s.\n", from, to);
#endif
if (link(from, to) < 0) { /* different file system? */
Reg4 int tofd;
tofd = creat(to, 0666);
if (tofd < 0) {
say3("patch: can't create %s, output is in %s.\n",
to, from);
return -1;
}
fromfd = open(from, 0);
if (fromfd < 0)
fatal2("patch: internal error, can't reopen %s\n", from);
while ((i=read(fromfd, buf, sizeof buf)) > 0)
if (write(tofd, buf, i) != i)
fatal1("patch: write failed\n");
Close(fromfd);
Close(tofd);
}
Unlink(from);
return 0;
}
#endif
/* Copy a file. */
void
copy_file(from,to)
char *from, *to;
{
Reg3 int tofd;
Reg2 int fromfd;
Reg1 int i;
tofd = creat(to, 0666);
if (tofd < 0)
fatal2("patch: can't create %s.\n", to);
fromfd = open(from, 0);
if (fromfd < 0)
fatal2("patch: internal error, can't reopen %s\n", from);
while ((i=read(fromfd, buf, sizeof buf)) > 0)
if (write(tofd, buf, i) != i)
fatal2("patch: write (%s) failed\n", to);
Close(fromfd);
Close(tofd);
}
/* Allocate a unique area for a string. */
char *
savestr(s)
Reg1 char *s;
{
Reg3 char *rv;
Reg2 char *t;
if (!s)
s = "Oops";
t = s;
while (*t++);
rv = malloc((MEM) (t - s));
if (rv == Nullch) {
if (using_plan_a)
out_of_mem = TRUE;
else
fatal1("patch: out of memory (savestr)\n");
}
else {
t = rv;
while (*t++ = *s++);
}
return rv;
}
#ifdef lint
#ifdef CANVARARG
/*VARARGS ARGSUSED*/
say(pat) char *pat; { ; }
/*VARARGS ARGSUSED*/
fatal(pat) char *pat; { ; }
/*VARARGS ARGSUSED*/
ask(pat) char *pat; { ; }
#endif
#else
/* Vanilla terminal output (buffered). */
void
say(pat,arg1,arg2,arg3)
char *pat;
long arg1,arg2,arg3;
{
fprintf(stderr, pat, arg1, arg2, arg3);
Fflush(stderr);
}
/* Terminal output, pun intended. */
void /* very void */
fatal(pat,arg1,arg2,arg3)
char *pat;
long arg1,arg2,arg3;
{
void my_exit();
say(pat, arg1, arg2, arg3);
my_exit(1);
}
#ifndef AMIGA
/* Get a response from the user, somehow or other. */
void
ask(pat,arg1,arg2,arg3)
char *pat;
long arg1,arg2,arg3;
{
int ttyfd;
int r;
bool tty2 = isatty(2);
Sprintf(buf, pat, arg1, arg2, arg3);
Fflush(stderr);
write(2, buf, strlen(buf));
if (tty2) { /* might be redirected to a file */
r = read(2, buf, sizeof buf);
}
else if (isatty(1)) { /* this may be new file output */
Fflush(stdout);
write(1, buf, strlen(buf));
r = read(1, buf, sizeof buf);
}
else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
/* might be deleted or unwriteable */
write(ttyfd, buf, strlen(buf));
r = read(ttyfd, buf, sizeof buf);
Close(ttyfd);
}
else if (isatty(0)) { /* this is probably patch input */
Fflush(stdin);
write(0, buf, strlen(buf));
r = read(0, buf, sizeof buf);
}
else { /* no terminal at all--default it */
buf[0] = '\n';
r = 1;
}
if (r <= 0)
buf[0] = 0;
else
buf[r] = '\0';
if (!tty2)
say1(buf);
}
#else /* Amiga */
/* for the Amiga we're going to have to do some heavy-duty magic.
We can't open /dev/tty! So open a whole new window!
*/
void
ask(pat,arg1,arg2,arg3)
char *pat;
long arg1,arg2,arg3;
{
int rwin;
long actual_read;
Sprintf(buf, pat, arg1, arg2, arg3);
rwin=open("CON:0/10/400/100/Patch Response Window",O_RDWR+O_CREAT);
if (rwin==0) {
printf("Error:No window dressing.");
}
write(rwin,buf,strlen(buf));
actual_read=read(rwin,buf,sizeof buf);
if (actual_read==0)
buf[0]=0;
buf[actual_read]=0;
/* printf("actual_read=%d buf=%s\n",actual_read,buf); */
Close(rwin);
}
#endif /* amiga */
#endif /* lint */
/* How to handle certain events when not in a critical region. */
void
set_signals(reset)
int reset;
{
void my_exit();
#ifdef AMIGA
extern short Enable_Abort;
Enable_Abort=1;
#else
#ifndef lint
#ifdef VOIDSIG
static void (*hupval)(),(*intval)();
#else
static int (*hupval)(),(*intval)();
#endif
if (!reset) {
hupval = signal(SIGHUP, SIG_IGN);
if (hupval != SIG_IGN)
#ifdef VOIDSIG
hupval = my_exit;
#else
hupval = (int(*)())my_exit;
#endif
intval = signal(SIGINT, SIG_IGN);
if (intval != SIG_IGN)
#ifdef VOIDSIG
intval = my_exit;
#else
intval = (int(*)())my_exit;
#endif
}
Signal(SIGHUP, hupval);
Signal(SIGINT, intval);
#endif
#endif
}
/* How to handle certain events when in a critical region. */
void
ignore_signals()
{
#ifdef AMIGA
extern short Enable_Abort;
Enable_Abort=0;
#else
#ifndef lint
Signal(SIGHUP, SIG_IGN);
Signal(SIGINT, SIG_IGN);
#endif
#endif
}
#ifdef AMIGA
extern int stat();
/*
This is more space-efficient than Larry's, but has the
disadvantage of groking with the other person's copy of the
string. Restores it before the end, but that's still nasty.
*/
void
makedirs(filename,striplast)
char *filename;
bool striplast;
{
register char *walkptr=filename;
register char temp;
extern char *index();
register struct FileLock *tmplock;
register int result;
extern struct FileLock *CreateDir();
struct stat *buf; /* for the stat() command. */
/* first the easy part: */
buf = (struct stat *) malloc(sizeof(struct stat));
if (walkptr[0]=='.' && walkptr[1]=='/')
walkptr+=2;
if (walkptr[0]=='/') /* starting at root: */
walkptr[0]=':'; /* AmigaDOS root. */
/* loop: */
for(;;) {
walkptr=index(walkptr,'/'); /* see if there's subdirectories. */
if (walkptr) {
temp=*walkptr;
*walkptr++=0; /* filename now points to dirname. */
} else if (striplast) /* top-of-loop exit, and... */
break;
result = stat(filename,buf);
/* If we can't create the directory, we'll sit here spinning till
the end of the filename. On the other hand, it don't really matter
what we do here. They won't be able to open the final file name upstairs,
so they'll say "can't create file" up there. Phew.
*/
if (result==-1) { /* make a directory... */
tmplock=CreateDir(filename);
UnLock(tmplock);
}
if (walkptr)
*(walkptr-1)=temp; /* restore what we did to his filename. */
else
break; /* bottom of loop exit. */
}
free(buf);
return;
}
#else
/* Make sure we'll have the directories to create a file. */
void
makedirs(filename,striplast)
Reg1 char *filename;
bool striplast;
{
char tmpbuf[256];
Reg2 char *s = tmpbuf;
char *dirv[20];
Reg3 int i;
Reg4 int dirvp = 0;
while (*filename) {
if (*filename == '/') {
filename++;
dirv[dirvp++] = s;
*s++ = '\0';
}
else {
*s++ = *filename++;
}
}
*s = '\0';
dirv[dirvp] = s;
if (striplast)
dirvp--;
if (dirvp < 0)
return;
strcpy(buf, "mkdir");
s = buf;
for (i=0; i<=dirvp; i++) {
while (*s) s++;
*s++ = ' ';
strcpy(s, tmpbuf);
*dirv[i] = '/';
}
system(buf);
}
#endif
#ifdef AMIGA
/* chmod to satisfy us: */
void chmod() {}
/* abort to satisfy us: */
void abort() { exit(1); }
#endif
/* Make filenames more reasonable. */
char *
fetchname(at,strip_leading,assume_exists)
char *at;
int strip_leading;
int assume_exists;
{
char *s;
char *name;
Reg1 char *t;
char tmpbuf[200];
if (!at)
return Nullch;
s = savestr(at);
for (t=s; isspace(*t); t++) ;
name = t;
#ifdef DEBUGGING
if (debug & 128)
say4("fetchname %s %d %d\n",name,strip_leading,assume_exists);
#endif
if (strnEQ(name, "/dev/null", 9)) /* so files can be created by diffing */
return Nullch; /* against /dev/null. */
for (; *t && !isspace(*t); t++)
if (*t == '/')
if (--strip_leading >= 0)
name = t+1;
*t = '\0';
if (name != s && *s != '/') {
name[-1] = '\0';
if (stat(s, &filestat) && filestat.st_mode & S_IFDIR) {
name[-1] = '/';
name=s;
}
}
name = savestr(name);
Sprintf(tmpbuf, "RCS/%s", name);
free(s);
if (stat(name, &filestat) < 0 && !assume_exists) {
#ifdef AMIGA
name = Nullch; /* Amiga doesn't have RCS. */
#else
Strcat(tmpbuf, RCSSUFFIX);
if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+4, &filestat) < 0) {
Sprintf(tmpbuf, "SCCS/%s%s", SCCSPREFIX, name);
if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+5, &filestat) < 0) {
free(name);
name = Nullch;
}
}
#endif
}
return name;
}